/*
 * This program is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation, either version 3 of the License, or (at your option) any later
 * version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program. If not, see <http://www.gnu.org/licenses/>.
 */
package com.l2device.gameserver.model.events.tvt;

import java.util.ArrayList;
import java.util.HashMap;

import com.l2device.gameserver.Config;
import com.l2device.gameserver.ThreadPoolManager;
import com.l2device.gameserver.model.actor.L2Character;
import com.l2device.gameserver.model.actor.instance.L2PcInstance;
import com.l2device.gameserver.network.serverpackets.ActionFailed;

/**
 * @author Anarchy
 *
 *This class contains restrictions and general methods for all events.
 */
public final class EventCommons
{
       public final HashMap<L2PcInstance, IEvent> _players;
       private final HashMap<L2PcInstance, Class<?>> _registeredPlayers;
      
       public static EventCommons getInstance()
       {
               return SingletonHolder._instance;
       }
      
       protected EventCommons()
       {
               _players = new HashMap<>();
               _registeredPlayers = new HashMap<>();
       }
      
       public void registerPlayer(L2PcInstance player, Class<?> c)
       {
               if (_registeredPlayers.containsKey(player))
               {
                       player.sendMessage("TvT: Вы уже зарегистрированы на ивент.");
                       return;
               }
              
               _registeredPlayers.put(player, c);
       }
      
       public void unregisterPlayer(L2PcInstance player, Class<?> c)
       {
               if (!_registeredPlayers.containsKey(player))
               {
                       player.sendMessage("TvT: Вы не зарегистрированы на ивент.");
                       return;
               }
              
               _registeredPlayers.remove(player);
       }
      
       public boolean showDiePacket(L2PcInstance player)
       {
               if (_players.containsKey(player))
               {
                       if (_players.get(player) instanceof TvTEvent)
                       {
                               return false;
                       }
               }
              
               return true;
       }
      
       public boolean canUnstuck(L2PcInstance player)
       {
               if (_players.containsKey(player))
               {
                       return false;
               }
              
               return true;
       }
      
       public boolean canRes(L2PcInstance victim)
       {
               if (_players.containsKey(victim))
               {
                       return false;
               }
              
               return true;
       }
      
       public boolean canRecall(L2PcInstance victim)
       {
               if (_players.containsKey(victim))
               {
                       return false;
               }
              
               return true;
       }
      
       public void doDie(L2Character killer, L2PcInstance victim)
       {
               if (_players.containsKey(victim))
               {
                       if (killer != null && killer instanceof L2PcInstance)
                       {
                               L2PcInstance kl = (L2PcInstance)killer;
                              
                               if (_players.containsKey(kl))
                               {
                                       if (_players.get(victim) == _players.get(kl))
                                       {
                                               // TvT event kills.
                                               if (_players.get(victim) instanceof TvTEvent)
                                               {
                                                       if (kl.getEventTeam() != victim.getEventTeam())
                                                       {
                                                               kl.getEventTeam().addPoints(1);
                                                       }
                                                      
                                                       ThreadPoolManager.getInstance().scheduleGeneral(new ResTask(victim.getEventTeam().getRespawnX(), victim.getEventTeam().getRespawnY(), victim.getEventTeam().getRespawnZ(), victim, true),Config.TVT_RES_SECONDS * 1000);
                                               }
                                       }
                               }
                       }
               }
       }
      
       public boolean canTarget(L2PcInstance player, L2PcInstance target)
       {
               if ((!_players.containsKey(player) && _players.containsKey(target))
                               || (_players.containsKey(player) && !_players.containsKey(target)))
               {
                       player.setTarget(null);
                       player.sendPacket(ActionFailed.STATIC_PACKET);
                       return false;
               }
              
               if (_players.get(player) != _players.get(target))
               {
                       player.setTarget(null);
                       player.sendPacket(ActionFailed.STATIC_PACKET);
                       return false;
               }
              
               if ((target.getEventTeam() != null && player.getEventTeam() == null))
               {
                       player.setTarget(null);
                       player.sendPacket(ActionFailed.STATIC_PACKET);
                       return false;
               }
              
               if (target.getEventTeam() == null && player.getEventTeam() != null)
               {
                       player.setTarget(null);
                       player.sendPacket(ActionFailed.STATIC_PACKET);
                       return false;
               }
              
               return true;
       }
      
       public void addPlayer(L2PcInstance player, IEvent event)
       {
               if (!_players.containsKey(player))
               {
                       _players.put(player, event);
               }
       }
      
       public void removePlayer(L2PcInstance player)
       {
               if (_players.containsKey(player))
               {
                       _players.remove(player);
               }
       }
      
       public int getRegisteredPlayersSize(Class<?> c)
       {
               int i = 0;
               for (L2PcInstance p : _registeredPlayers.keySet())
               {
                       if (_registeredPlayers.get(p) == c)
                       {
                               i++;
                       }
               }
              
               return i;
       }
      
       public void removeRegisteredPlayers(Class<?> c)
       {
               ArrayList<L2PcInstance> temp = new ArrayList<>();
              
               for (L2PcInstance p : _registeredPlayers.keySet())
               {
                       if (_registeredPlayers.get(p) == c)
                       {
                               temp.add(p);
                       }
               }
              
               for (L2PcInstance p : temp)
               {
                       _registeredPlayers.remove(p);
               }
       }
      
       public HashMap<L2PcInstance, Class<?>> getRegisteredPlayers()
       {
               return _registeredPlayers;
       }
      
       public ArrayList<L2PcInstance> getRegisteredPlayers(Class<?> c)
       {
               ArrayList<L2PcInstance> temp = new ArrayList<>();
              
               for (L2PcInstance p : _registeredPlayers.keySet())
               {
                       if (_registeredPlayers.get(p) == c)
                       {
                               temp.add(p);
                       }
               }
              
               return temp;
       }
      
       public class ResTask implements Runnable
       {
               private final int _x, _y, _z;
               private final L2PcInstance _player;
               private final boolean _heal;
              
               public ResTask(int x, int y, int z, L2PcInstance player, boolean heal)
               {
                       _x = x;
                       _y = y;
                       _z = z;
                       _player = player;
                       _heal = heal;
               }
              
               @Override
               public void run()
               {
                       _player.doRevive();
                       _player.teleToLocation(_x, _y, _z, 0);
                       if (_heal)
                       {
                               _player.setCurrentHpMp(_player.getMaxHp(), _player.getMaxMp());
                               _player.setCurrentCp(_player.getMaxCp());
                       }
               }
       }
      
       private static class SingletonHolder
       {
               protected static final EventCommons _instance = new EventCommons();
       }
}